/**
 * Created by Administrator on 2015/12/3.
 */

(function ($, angular, d3) {

    var app = angular.module('module', [])

    app.controller('plain_category', ['$scope', '$http', function ($scope, $http) {
        var margin = {top: 20, right: 120, bottom: 20, left: 120},
            width = 760 - margin.right - margin.left,
            height = 600 - margin.top - margin.bottom;

        var i = 0,
            duration = 750,
            root;

        var tree = d3.layout.tree()
            .size([height, width]);

        var diagonal = d3.svg.diagonal()
            .projection(function (d) {
                return [d.y, d.x];
            });

        var svg = d3.select("#brain_category").append("svg")
            .attr("width", width + margin.right + margin.left)
            .attr("height", height + margin.top + margin.bottom)
            .append("g")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

        d3.json("/admin/statistics/plain/brain/category", function (error, flare) {
            if (error) throw error;

            root = {
                name: '顶级',
                children: flare.categories,
                x0: height / 2,
                y0: 0
            }

            function collapse(d) {
                if (d.children) {
                    d._children = d.children;
                    d._children.forEach(collapse);
                    d.children = null;
                } else {
                    d.size = 400
                }
            }

            root.children.forEach(collapse);
            update(root);
        });

        d3.select(self.frameElement).style("height", "800px");

        function update(source) {

            // Compute the new tree layout.
            var nodes = tree.nodes(root).reverse(),
                links = tree.links(nodes);

            // Normalize for fixed-depth.
            nodes.forEach(function (d) {
                d.y = d.depth * 180;
            });

            // Update the nodes…
            var node = svg.selectAll("g.node")
                .data(nodes, function (d) {
                    return d.id || (d.id = ++i);
                });

            // Enter any new nodes at the parent's previous position.
            var nodeEnter = node.enter().append("g")
                .attr("class", "node")
                .attr("transform", function (d) {
                    return "translate(" + source.y0 + "," + source.x0 + ")";
                })
                .on("click", click);

            nodeEnter.append("circle")
                .attr("r", 1e-6)
                .style("fill", function (d) {
                    return d._children ? "lightsteelblue" : "#fff";
                });

            nodeEnter.append("text")
                .attr("x", function (d) {
                    return d.children || d._children ? -10 : 10;
                })
                .attr("dy", ".35em")
                .attr("text-anchor", function (d) {
                    return d.children || d._children ? "end" : "start";
                })
                .text(function (d) {
                    return d.name;
                })
                .style("fill-opacity", 1e-6);

            // Transition nodes to their new position.
            var nodeUpdate = node.transition()
                .duration(duration)
                .attr("transform", function (d) {
                    return "translate(" + d.y + "," + d.x + ")";
                });

            nodeUpdate.select("circle")
                .attr("r", 4.5)
                .style("fill", function (d) {
                    return d._children ? "lightsteelblue" : "#fff";
                });

            nodeUpdate.select("text")
                .style("fill-opacity", 1);

            // Transition exiting nodes to the parent's new position.
            var nodeExit = node.exit().transition()
                .duration(duration)
                .attr("transform", function (d) {
                    return "translate(" + source.y + "," + source.x + ")";
                })
                .remove();

            nodeExit.select("circle")
                .attr("r", 1e-6);

            nodeExit.select("text")
                .style("fill-opacity", 1e-6);

            // Update the links…
            var link = svg.selectAll("path.link")
                .data(links, function (d) {
                    return d.target.id;
                });

            // Enter any new links at the parent's previous position.
            link.enter().insert("path", "g")
                .attr("class", "link")
                .attr("d", function (d) {
                    var o = {x: source.x0, y: source.y0};
                    return diagonal({source: o, target: o});
                });

            // Transition links to their new position.
            link.transition()
                .duration(duration)
                .attr("d", diagonal);

            // Transition exiting nodes to the parent's new position.
            link.exit().transition()
                .duration(duration)
                .attr("d", function (d) {
                    var o = {x: source.x, y: source.y};
                    return diagonal({source: o, target: o});
                })
                .remove();

            // Stash the old positions for transition.
            nodes.forEach(function (d) {
                d.x0 = d.x;
                d.y0 = d.y;
            });
        }

// Toggle children on click.
        function click(d) {
            if (d.children) {
                d._children = d.children;
                d.children = null;
            } else {
                d.children = d._children;
                d._children = null;
            }
            update(d);
        }
    }])


    app.controller('plain_partition', ['$scope', '$http', function ($scope, $http) {

        var margin = {top: 200, right: 330, bottom: 290, left: 330},
            radius = Math.min(margin.top, margin.right, margin.bottom, margin.left) - 10;

        function filter_min_arc_size_text(d, i) {
            return (d.dx * d.depth * radius / 3) > 14
        };
        var hue = d3.scale.category10();
        var luminance = d3.scale.sqrt()
            .domain([0, 1e6])
            .clamp(true)
            .range([90, 20]);
        var svg = d3.select("#partition").append("svg")
            .attr("width", margin.left + margin.right)
            .attr("height", margin.top + margin.bottom)
            .append("g")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
        var partition = d3.layout.partition()
            .sort(function (a, b) {
                return d3.ascending(a.name, b.name);
            })
            .size([2 * Math.PI, radius]);
        var arc = d3.svg.arc()
            .startAngle(function (d) {
                return d.x;
            })
            .endAngle(function (d) {
                return d.x + d.dx - .01 / (d.depth + .5);
            })
            .innerRadius(function (d) {
                return radius / 3 * d.depth;
            })
            .outerRadius(function (d) {
                return radius / 3 * (d.depth + 1) - 1;
            });
//Tooltip description
        var tooltip = d3.select("#partition")
            .append("div")
            .attr("id", "tooltip")
            .style("position", "absolute")
            .style("z-index", "10")
            .style("opacity", 0);

        function format_number(x) {
            return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
        }

        function format_description(d) {
            var description = d.description;
            return '<b>' + d.name + '</b></br>' + d.description + '<br> (' + format_number(d.value) + ')';
        }

        function computeTextRotation(d) {
            var angle = (d.x + d.dx / 2) * 180 / Math.PI - 90

            return angle;
        }

        function mouseOverArc(d) {
            d3.select(this).attr("stroke", "black")

            tooltip.html(format_description(d));
            return tooltip.transition()
                .duration(50)
                .style("opacity", 0.9);
        }

        function mouseOutArc() {
            d3.select(this).attr("stroke", "")
            return tooltip.style("opacity", 0);
        }

        function mouseMoveArc(d) {
            return tooltip
                .style("top", (d3.event.pageY - 10) + "px")
                .style("left", (d3.event.pageX + 10) + "px");
        }

        var root_ = null;
        d3.json("/admin/statistics/plain/partition/category", function (error, root) {
            if (error) return console.warn(error);
            // Compute the initial layout on the entire tree to sum sizes.
            // Also compute the full name and fill color for each node,
            // and stash the children so they can be restored as we descend.

            root = {
                name: '顶节点',
                children: root.categories
            }



            partition
                .value(function (d) {
                    return d.size;
                })
                .nodes(root)
                .forEach(function (d) {
                    d._children = d.children;
                    d.sum = d.size;
                    d.key = key(d);
                    d.fill = fill(d);
                });
            // Now redefine the value function to use the previously-computed sum.
            partition
                .children(function (d, depth) {
                    return depth < 3 ? d._children : null;
                })
                .value(function (d) {
                    return d.sum;
                });
            var center = svg.append("circle")
                .attr("r", radius / 3)
                .on("click", zoomOut);
            center.append("title")
                .text("zoom out");

            var partitioned_data = partition.nodes(root).slice(1)
            var path = svg.selectAll("path")
                .data(partitioned_data)
                .enter().append("path")
                .attr("d", arc)
                .style("fill", function (d) {
                    return d.fill;
                })
                .each(function (d) {
                    this._current = updateArc(d);
                })
                .on("click", zoomIn)
                .on("mouseover", mouseOverArc)
                .on("mousemove", mouseMoveArc)
                .on("mouseout", mouseOutArc);


            var texts = svg.selectAll("text")
                .data(partitioned_data)
                .enter().append("text")
                .filter(filter_min_arc_size_text)
                .attr("transform", function (d) {
                    return "rotate(" + computeTextRotation(d) + ")";
                })
                .attr("x", function (d) {
                    return radius / 3 * d.depth;
                })
                .attr("dx", "6") // margin
                .attr("dy", ".35em") // vertical-align
                .text(function (d, i) {
                    return d.name
                })

            function zoomIn(p) {
                if (p.depth > 1) p = p.parent;
                if (!p.children) return;
                zoom(p, p);
            }

            function zoomOut(p) {
                if (!p.parent) return;
                zoom(p.parent, p);
            }

            // Zoom to the specified new root.
            function zoom(root, p) {
                if (document.documentElement.__transition__) return;
                // Rescale outside angles to match the new layout.
                var enterArc,
                    exitArc,
                    outsideAngle = d3.scale.linear().domain([0, 2 * Math.PI]);

                function insideArc(d) {
                    return p.key > d.key
                        ? {depth: d.depth - 1, x: 0, dx: 0} : p.key < d.key
                        ? {depth: d.depth - 1, x: 2 * Math.PI, dx: 0}
                        : {depth: 0, x: 0, dx: 2 * Math.PI};
                }

                function outsideArc(d) {
                    return {depth: d.depth + 1, x: outsideAngle(d.x), dx: outsideAngle(d.x + d.dx) - outsideAngle(d.x)};
                }

                center.datum(root);
                // When zooming in, arcs enter from the outside and exit to the inside.
                // Entering outside arcs start from the old layout.
                if (root === p) enterArc = outsideArc, exitArc = insideArc, outsideAngle.range([p.x, p.x + p.dx]);

                var new_data = partition.nodes(root).slice(1)
                path = path.data(new_data, function (d) {
                    return d.key;
                });

                // When zooming out, arcs enter from the inside and exit to the outside.
                // Exiting outside arcs transition to the new layout.
                if (root !== p) enterArc = insideArc, exitArc = outsideArc, outsideAngle.range([p.x, p.x + p.dx]);
                d3.transition().duration(d3.event.altKey ? 7500 : 750).each(function () {
                    path.exit().transition()
                        .style("fill-opacity", function (d) {
                            return d.depth === 1 + (root === p) ? 1 : 0;
                        })
                        .attrTween("d", function (d) {
                            return arcTween.call(this, exitArc(d));
                        })
                        .remove();

                    path.enter().append("path")
                        .style("fill-opacity", function (d) {
                            return d.depth === 2 - (root === p) ? 1 : 0;
                        })
                        .style("fill", function (d) {
                            return d.fill;
                        })
                        .on("click", zoomIn)
                        .on("mouseover", mouseOverArc)
                        .on("mousemove", mouseMoveArc)
                        .on("mouseout", mouseOutArc)
                        .each(function (d) {
                            this._current = enterArc(d);
                        });

                    path.transition()
                        .style("fill-opacity", 1)
                        .attrTween("d", function (d) {
                            return arcTween.call(this, updateArc(d));
                        });


                });


                texts = texts.data(new_data, function (d) {
                    return d.key;
                })

                texts.exit()
                    .remove()
                texts.enter()
                    .append("text")

                texts.style("opacity", 0)
                    .attr("transform", function (d) {
                        return "rotate(" + computeTextRotation(d) + ")";
                    })
                    .attr("x", function (d) {
                        return radius / 3 * d.depth;
                    })
                    .attr("dx", "6") // margin
                    .attr("dy", ".35em") // vertical-align
                    .filter(filter_min_arc_size_text)
                    .text(function (d, i) {
                        return d.name
                    })
                    .transition().delay(750).style("opacity", 1)


            }
        });
        function key(d) {
            var k = [], p = d;
            while (p.depth) k.push(p.name), p = p.parent;
            return k.reverse().join(".");
        }

        function fill(d) {
            var p = d;
            while (p.depth > 1) p = p.parent;
            var c = d3.lab(hue(p.name));
            c.l = luminance(d.sum);
            return c;
        }

        function arcTween(b) {
            var i = d3.interpolate(this._current, b);
            this._current = i(0);
            return function (t) {
                return arc(i(t));
            };
        }

        function updateArc(d) {
            return {depth: d.depth, x: d.x, dx: d.dx};
        }

        d3.select(self.frameElement).style("height", margin.top + margin.bottom + "px");


    }])


    app.controller('plain_histogram_recipe', ['$scope', '$http', function ($scope, $http) {

        var margin = {top: 20, right: 30, bottom: 30, left: 40},
            width = 960 - margin.left - margin.right,
            height = 500 - margin.top - margin.bottom;

        var x = d3.scale.ordinal()
            .rangeRoundBands([0, width], .1);

        var y = d3.scale.linear()
            .range([height, 0]);

        var xAxis = d3.svg.axis()
            .scale(x)
            .orient("bottom");

        var yAxis = d3.svg.axis()
            .scale(y)
            .orient("left");

        var chart = d3.select("#histogram_recipe").append('svg')
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom)
            .append("g")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");


        d3.json("/admin/statistics/plain/histogram/recipe", function (error, data) {

            var temp = []
            var m = 1
            for (var i = 0; i < data.length; i++) {
                for (; m < +data[i].name; m++) {
                    if (m < 10) {
                        temp.push({name: '0' + m, value: 0})
                    } else {
                        temp.push({name: '' + m, value: 0})
                    }
                }
                temp.push(data[i])
                ++m
            }

            data = temp


            x.domain(data.map(function (d) {
                return d.name;
            }));
            y.domain([0, d3.max(data, function (d) {
                return d.value;
            })]);

            chart.append("g")
                .attr("class", "x axis")
                .attr("transform", "translate(0," + height + ")")
                .call(xAxis);

            chart.append("g")
                .attr("class", "y axis")
                .call(yAxis);

            chart.selectAll(".bar")
                .data(data)
                .enter().append("rect")
                .attr("class", "bar")
                .attr("x", function (d) {
                    return x(d.name);
                })
                .attr("y", function (d) {
                    return y(d.value);
                })
                .attr("height", function (d) {
                    return height - y(d.value);
                })
                .attr("width", x.rangeBand());
        });
    }])


    app.controller('plain_line_menu', ['$scope', '$http', function ($scope, $http) {
        var margin = {top: 20, right: 20, bottom: 30, left: 50},
            width = 960 - margin.left - margin.right,
            height = 500 - margin.top - margin.bottom;

        var x = d3.scale.ordinal()
            .rangePoints([0, width]);

        var y = d3.scale.linear()
            .range([height, 0]);

        var xAxis = d3.svg.axis()
            .scale(x)
            .orient("bottom");

        var yAxis = d3.svg.axis()
            .scale(y)
            .orient("left");

        var line = d3.svg.line()
            .x(function (d) {
                return x(d.date);
            })
            .y(function (d) {
                return y(d.value);
            });

        var svg = d3.select("#line_menu").append("svg")
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom)
            .append("g")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

        d3.json("/admin/statistics/plain/line/menu", function (error, data) {
            if (error) throw error;

            var temp = []
            var m = 1
            for (var i = 0; i < data.length; i++) {
                for (; m < +data[i].date; m++) {
                    if (m < 10) {
                        temp.push({date: '0' + m, value: 0})
                    } else {
                        temp.push({date: '' + m, value: 0})
                    }
                }
                temp.push(data[i])
                ++m
            }

            data = temp

            x.domain(data.map(function (d) {
                return d.date;
            }));
            y.domain([0, d3.max(data, function (d) {
                return d.value;
            }) * 3 / 2]);

            svg.append("g")
                .attr("class", "x axis")
                .attr("transform", "translate(0," + height + ")")
                .call(xAxis);

            svg.append("g")
                .attr("class", "y axis")
                .call(yAxis)
                .append("text")
                .attr("transform", "rotate(-90)")
                .attr("y", 6)
                .attr("dy", ".71em")
                .style("text-anchor", "end")
                .text("数量 (个)");

            svg.append("path")
                .datum(data)
                .attr("class", "line")
                .attr("d", line);
        });
    }])

    app.controller('plain_line_user', ['$scope', '$http', function ($scope, $http) {
        var margin = {top: 20, right: 20, bottom: 30, left: 50},
            width = 960 - margin.left - margin.right,
            height = 500 - margin.top - margin.bottom;

        var x = d3.scale.ordinal()
            .rangePoints([0, width]);

        var y = d3.scale.linear()
            .range([height, 0]);

        var xAxis = d3.svg.axis()
            .scale(x)
            .orient("bottom");

        var yAxis = d3.svg.axis()
            .scale(y)
            .orient("left");

        var line = d3.svg.line()
            .x(function (d) {
                return x(d.date);
            })
            .y(function (d) {
                return y(d.value);
            });

        var svg = d3.select("#line_user").append("svg")
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom)
            .append("g")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

        d3.json("/admin/statistics/plain/line/user", function (error, data) {
            if (error) throw error;

            var temp = []
            var m = 1
            for (var i = 0; i < data.length; i++) {
                for (; m < +data[i].date; m++) {
                    if (m < 10) {
                        temp.push({date: '0' + m, value: 0})
                    } else {
                        temp.push({date: '' + m, value: 0})
                    }
                }
                temp.push(data[i])
                ++m
            }

            data = temp

            x.domain(data.map(function (d) {
                return d.date;
            }));
            y.domain([0, d3.max(data, function (d) {
                return d.value;
            }) * 3 / 2]);

            svg.append("g")
                .attr("class", "x axis")
                .attr("transform", "translate(0," + height + ")")
                .call(xAxis);

            svg.append("g")
                .attr("class", "y axis")
                .call(yAxis)
                .append("text")
                .attr("transform", "rotate(-90)")
                .attr("y", 6)
                .attr("dy", ".71em")
                .style("text-anchor", "end")
                .text("数量 (个)");

            svg.append("path")
                .datum(data)
                .attr("class", "line")
                .attr("d", line);
        });
    }])

    app.controller('plain_pie_gender_scale', ['$scope', '$http', function ($scope, $http) {
        var width = 760,
            height = 300,
            radius = Math.min(width, height) / 2;

        var color = d3.scale.ordinal()
            .range(["#98abc5", "#8a89a6"]);

        var arc = d3.svg.arc()
            .outerRadius(radius - 10)
            .innerRadius(0);

        var labelArc = d3.svg.arc()
            .outerRadius(radius - 40)
            .innerRadius(radius - 40);

        var pie = d3.layout.pie()
            .sort(null)
            .value(function (d) {
                return d.count;
            });

        var svg = d3.select("#pie_gender_scale").append("svg")
            .attr("width", width)
            .attr("height", height)
            .append("g")
            .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

        d3.json("/admin/statistics/plain/pie/gender/scale", function (error, data) {
            if (error) throw error;

            var g = svg.selectAll(".arc")
                .data(pie(data))
                .enter().append("g")
                .attr("class", "arc");

            g.append("path")
                .attr("d", arc)
                .style("fill", function (d) {
                    return color(d.data.gender);
                });

            g.append("text")
                .attr("transform", function (d) {
                    return "translate(" + labelArc.centroid(d) + ")";
                })
                .attr("dy", ".35em")
                .text(function (d) {
                    return d.data.gender;
                });
        });
    }])


})(jQuery, angular, d3)